home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / ingres04.lzh / source / gutil / ftoa.c < prev    next >
Encoding:
C/C++ Source or Header  |  1985-01-23  |  3.2 KB  |  191 lines

  1. # include    <sccs.h>
  2.  
  3. SCCSID(@(#)ftoa.c    8.1    12/31/84)
  4.  
  5. # define    MAXDIG        25
  6.  
  7. /*
  8. **  FLOATING POINT TO ASCII CONVERSION
  9. **
  10. **    'Value' is converted to an ascii character string and stored
  11. **    into 'ascii'.  Ascii should have room for at least 'width' + 1
  12. **    characters.  'Width' is the width of the output field (max).
  13. **    'Prec' is the number of characters to put after the decimal
  14. **    point.  The format of the output string is controlled by
  15. **    'format'.
  16. **
  17. **    'Format' can be:
  18. **        e or E: "E" format output
  19. **        f or F:  "F" format output
  20. **        g or G:  "F" format output if it will fit, otherwise
  21. **            use "E" format.
  22. **        n or N:  same as G, but decimal points will not always
  23. **            be aligned.
  24. **
  25. **    If 'format' is upper case, the "E" comes out in upper case;
  26. **    otherwise it comes out in lower case.
  27. **
  28. **    When the field width is not big enough, it fills the field with
  29. **    stars ("*****") and returns zero.  Normal return is the width
  30. **    of the output field (sometimes shorter than 'width').
  31. */
  32.  
  33. ftoa(value, ascii, width, prec1, format)
  34. double    value;
  35. char    *ascii;
  36. int    width;
  37. int    prec1;
  38. char    format;
  39. {
  40.     auto int    expon;
  41.     auto int    sign;
  42.     register int    avail;
  43.     register char    *a;
  44.     register char    *p;
  45.     char        mode;
  46.     int        lowercase;
  47.     int        prec;
  48.     extern char    *ecvt(), *fcvt();
  49.  
  50.     prec = prec1;
  51.     mode = format;
  52.     lowercase = 'a' - 'A';
  53.     if (mode >= 'a')
  54.         mode -= 'a' - 'A';
  55.     else
  56.         lowercase = 0;
  57.  
  58.     if (mode != 'E')
  59.     {
  60.         /* try 'F' style output */
  61.         p = fcvt(value, prec, &expon, &sign);
  62.         avail = width;
  63.         a = ascii;
  64.  
  65.         /* output sign */
  66.         if (sign)
  67.         {
  68.             avail--;
  69.             *a++ = '-';
  70.         }
  71.  
  72.         /* output '0' before the decimal point */
  73.         if (expon <= 0)
  74.         {
  75.             *a++ = '0';
  76.             avail--;
  77.         }
  78.  
  79.         /* compute space length left after dec pt and fraction */
  80.         avail -= prec + 1;
  81.         if (mode == 'G')
  82.             avail -= 4;
  83.  
  84.         if (avail >= expon)
  85.         {
  86.  
  87.             /* it fits.  output */
  88.             while (expon > 0)
  89.             {
  90.                 /* output left of dp */
  91.                 expon--;
  92.                 if (*p)
  93.                 {
  94.                     *a++ = *p++;
  95.                 }
  96.                 else
  97.                     *a++ = '0';
  98.             }
  99.  
  100.             /* output fraction (right of dec pt) */
  101.             avail = expon;
  102.             goto frac_out;
  103.         }
  104.         /* won't fit; let's hope for G format */
  105.     }
  106.  
  107.     if (mode != 'F')
  108.     {
  109.         /* try to do E style output */
  110.         p = ecvt(value, prec + 1, &expon, &sign);
  111.         avail = width - 5;
  112.         a = ascii;
  113.  
  114.         /* output the sign */
  115.         if (sign)
  116.         {
  117.             *a++ = '-';
  118.             avail--;
  119.         }
  120.     }
  121.  
  122.     /* check for field too small */
  123.     if (mode == 'F' || avail < prec)
  124.     {
  125.         /* sorry joker, you lose */
  126.         a = ascii;
  127.         for (avail = width; avail > 0; avail--)
  128.             *a++ = '*';
  129.         *a = 0;
  130.         return (0);
  131.     }
  132.  
  133.     /* it fits; output the number */
  134.     mode = 'E';
  135.  
  136.     /* output the LHS single digit */
  137.     *a++ = *p++;
  138.     expon--;
  139.  
  140.     /* output the rhs */
  141.     avail = 1;
  142.  
  143.   frac_out:
  144.     *a++ = '.';
  145.     while (prec > 0)
  146.     {
  147.         prec--;
  148.         if (avail < 0)
  149.         {
  150.             avail++;
  151.             *a++ = '0';
  152.         }
  153.         else
  154.         {
  155.             if (*p)
  156.                 *a++ = *p++;
  157.             else
  158.                 *a++ = '0';
  159.         }
  160.     }
  161.  
  162.     /* output the exponent */
  163.     if (mode == 'E')
  164.     {
  165.         *a++ = 'E' + lowercase;
  166.         if (expon < 0)
  167.         {
  168.             *a++ = '-';
  169.             expon = -expon;
  170.         }
  171.         else
  172.             *a++ = '+';
  173.         *a++ = (expon / 10) % 10 + '0';
  174.         *a++ = expon % 10 + '0';
  175.     }
  176.  
  177.     /* output spaces on the end in G format */
  178.     if (mode == 'G')
  179.     {
  180.         *a++ = ' ';
  181.         *a++ = ' ';
  182.         *a++ = ' ';
  183.         *a++ = ' ';
  184.     }
  185.  
  186.     /* finally, we can return */
  187.     *a = 0;
  188.     avail = a - ascii;
  189.     return (avail);
  190. }
  191.